/* 
- Cookie Session 缺点：

Cookie会被附加在每个HTTP请求中，所以无形中增加了流量（事实上某些请求是不需要的）；
Cookie是明文传递的，所以存在安全性的问题；
Cookie的大小限制是4KB，对于复杂的需求来说是不够的；
对于浏览器外的其他客户端（比如iOS、Android），必须手动的设置cookie和session；
对于分布式系统和服务器集群中如何可以保证其他系统也可以正确的解析session？

- token校验
token可以翻译为令牌；
也就是在验证了用户账号和密码正确的情况，给用户颁发一个令牌；
这个令牌作为后续用户访问一些接口或者资源的凭证；
我们可以根据这个凭证来判断用户是否有权限来访问；

- 生成token：登录的时候，颁发token；
- 验证token：访问某些资源或者接口时，验证token；

JWT实现token机制
全称 Java Web Token

- JWT 生成的token 由三部分组成
  - header
    alg：采用的加密算法，默认是 HMAC SHA256（HS256），采用同一个密钥进行加密和解密；
    typ：JWT，固定值，通常都写成JWT即可；
    会通过base64Url算法进行编码；
  - payload
    携带的数据，比如我们可以将用户的id和name放到payload中；
    默认也会携带iat（issued at），令牌的签发时间；
    我们也可以设置过期时间：exp（expiration time）；
    会通过base64Url算法进行编码
  - signature
    设置一个secretKey，通过将前两个的结果合并后进行HMACSHA256的算法；
    HMACSHA256(base64Url(header)+.+base64Url(payload), secretKey);
    但是如果secretKey暴露是一件非常危险的事情，因为之后就可以模拟颁发token，也可以解密token；
*/

/* 
代码实现

pnpm i javawebtoken

const secretkey = 'aaaxxxx';
userRouter.get('/login' , (ctx,next)=>{
  // 颁发token 验证用户信息
  const payload = {id :111 , name:"lrq"} // 携带的参数
  const token = jwt.sign(payload , secretkey ,{
    expiresIn: 60, // 过期时间 单位s
    algorithm:"HS256" , // 加密方式 默认是HS256  也可以使用RS256 使用一对公钥私钥
  })
})

// 客户端再次发请求的时候 会在header中携带token  服务端进行验证token

userRouter.get('/list' , (ctx,next)=>{
  // 获取从客户端携带的token
  const { authorization } = ctx.headers
  const token = authorization.replace('Bearer' ,'' )
  try{
    // 验证token
    const res = jwt.verify(token , secretkey)
    ctx.body = {
      code:0 ,
      data:[{id:1,name:"商品1"}]
    }
  }catch(err){
    ctx.body = {
      code:-11,
      message:'token过期或无效的token'
    }
  }
})


*/